using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;

namespace extend_360.utils
{
    public class WindowsAPIUtils
    {
        // 定义键盘和鼠标事件常量
        // 定义键盘和鼠标事件常量
        private const int KEYEVENTF_KEYDOWN = 0x0000;
        private const uint PROCESS_TERMINATE = 0x0001;
        private const int KEYEVENTF_KEYUP = 0x0002;
        private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const int MOUSEEVENTF_LEFTUP = 0x0004;
        private const int MOUSEEVENTF_WHEEL = 0x0800;
        private const uint SWP_NOSIZE = 0x0001;
        private const uint SWP_NOZORDER = 0x0004;
        private const int SW_SHOWNORMAL = 1;
        public const int BM_CLICK = 0x00F5;
        public const uint WM_LBUTTONDOWN = 0x0201;
        public const uint WM_LBUTTONUP = 0x0202;
        public const uint GW_ENABLEDPOPUP = 6;

        private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); // 置于所有窗口之上

        /// <summary>
        /// 定义矩形结构体用于获取窗口位置
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        #region 获取系统分辨率

        [StructLayout(LayoutKind.Sequential)]
        public struct DEVMODE
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string dmDeviceName;

            public short dmSpecVersion;
            public short dmDriverVersion;
            public short dmSize;
            public short dmDriverExtra;
            public int dmFields;
            public int dmPositionX;
            public int dmPositionY;
            public int dmDisplayOrientation;
            public int dmDisplayFixedOutput;
            public short dmColor;
            public short dmDuplex;
            public short dmYResolution;
            public short dmTTOption;
            public short dmCollate;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string dmFormName;

            public short dmLogPixels;
            public int dmBitsPerPel;
            public int dmPelsWidth;
            public int dmPelsHeight;
            public int dmDisplayFlags;
            public int dmDisplayFrequency;
            public int dmICMMethod;
            public int dmICMIntent;
            public int dmMediaType;
            public int dmDitherType;
            public int dmReserved1;
            public int dmReserved2;
            public int dmPanningWidth;
            public int dmPanningHeight;
        }

        [DllImport("user32.dll")]
        public static extern bool EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);

        [DllImport("user32.dll")]
        public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);

        #endregion

        // 导入 Windows API 函数用于模拟键盘和鼠标输入
        [DllImport("user32.dll")]
        private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
            UIntPtr dwExtraInfo);

        [DllImport("user32.dll")]
        private static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData,
            UIntPtr dwExtraInfo);

        /// <summary>
        ///    模拟鼠标移动位置
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool SetCursorPos(int x, int y);

        /// <summary>
        /// 获取当前窗口
        /// </summary>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

        /// <summary>
        /// 将窗口设置为前台窗口（选中状态）
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// 获取窗体区域
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="lpRect"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

        // 导入 Windows API
        [DllImport("user32.dll")]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy,
            uint uFlags);

        /// <summary>
        /// 显示窗体
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="nCmdShow"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);


        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text,
            int count);

        // 导入 FindWindow
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        // 导入 FindWindowEx API
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,
            string windowTitle);

        public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

        /// <summary>
        /// 可见窗口
        /// </summary>
        /// <param name="enumProc"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);


        [DllImport("user32.dll")]
        public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr hObject);

        /// <summary>
        /// 设置窗体位置
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public static void SetWindowPos(IntPtr hWnd, int x, int y)
        {
            SetWindowPos(hWnd, HWND_TOPMOST, x, 0, y, 0, SWP_NOSIZE | SWP_NOZORDER);
        }

        /**
       * 获取当前窗口的标题
       */
        public static string GetCurrentWindowTitle()
        {
            const int nChars = 256;
            System.Text.StringBuilder title = new System.Text.StringBuilder(nChars);
            IntPtr hwnd = GetForegroundWindow();
            if (GetWindowText(hwnd, title, nChars) > 0)
            {
                return title.ToString();
            }

            return null;
        }

        /// <summary>
        /// 查找窗口句柄
        /// </summary>
        /// <param name="windowTitle"></param>
        /// <returns></returns>
        public static IntPtr FindWindowByTitle(string lpClassName, string windowTitle)
        {
            return FindWindow(lpClassName, windowTitle);
        }

        // 模拟键盘按下
        public static void KeyDown(byte keyCode)
        {
            keybd_event(keyCode, 0, KEYEVENTF_KEYDOWN, UIntPtr.Zero);
        }

        // 模拟键盘松开
        public static void KeyUp(byte keyCode)
        {
            keybd_event(keyCode, 0, KEYEVENTF_KEYUP, UIntPtr.Zero);
        }

        // 模拟鼠标滚动
        public static void MouseScroll(int delta)
        {
            mouse_event(MOUSEEVENTF_WHEEL, 0, 0, (uint)delta, UIntPtr.Zero);
        }

        // 模拟鼠标点击
        public static void MouseClick()
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, UIntPtr.Zero); // 按下左键
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, UIntPtr.Zero); // 松开左键
        }

        /// <summary>
        /// 关闭进程
        /// </summary>
        /// <param name="processes"></param>
        public static void KillProcess(Process[] processes)
        {
            if (processes == null)
                return;
            foreach (var process in processes)
            {
                IntPtr hProcess = OpenProcess(PROCESS_TERMINATE, false, process.Id);
                if (hProcess == IntPtr.Zero)
                {
                    SystemUtils.ConsoleWrite($"无法打开进程 {process.Id}，错误代码：{Marshal.GetLastWin32Error()}",
                        ConsoleColor.Red);
                    return;
                }

                if (!TerminateProcess(hProcess, 0))
                {
                    SystemUtils.ConsoleWrite($"无法终止进程 {process.Id}，错误代码：{Marshal.GetLastWin32Error()}",
                        ConsoleColor.Red);
                }

                CloseHandle(hProcess);
            }
        }

        /// <summary>
        /// 设置分辨率的函数
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="refreshRate"></param>
        /// <returns></returns>
        public static bool SetResolution(int width, int height)
        {
            DEVMODE dm = new DEVMODE();
            dm.dmSize = (short)Marshal.SizeOf(dm);
            // 获取当前显示设置
            EnumDisplaySettings(null, -1, ref dm);
            // 设置新的分辨率
            dm.dmPelsWidth = 1440;
            dm.dmPelsHeight = 900;
            dm.dmFields = 0x00180000; // DM_PELSWIDTH | DM_PELSHEIGHT
            // 应用新设置
            int result = ChangeDisplaySettings(ref dm, 0x01); // 
            // 返回是否成功
            return result == 0; // DISP_CHANGE_SUCCESSFUL
        }
    }
}